<template>
  <el-dialog :title="title" v-model="visible" class="dialog-sm" append-to-body @close="visible = false">
    <el-form ref="formRef" :model="form" :rules="rules" label-width="80px" v-loading="loading">
      <el-form-item label="角色名称" prop="name">
        <el-input v-model="form.name" placeholder="请输入角色名称" maxlength="64" />
      </el-form-item>
      <el-form-item label="权限字符" prop="role_key">
        <el-input v-model="form.role_key" placeholder="请输入权限字符" maxlength="128" />
      </el-form-item>
      <el-form-item label="角色顺序" prop="list_sort">
        <el-input-number v-model="form.list_sort" controls-position="right" :min="0" />
      </el-form-item>
      <el-form-item label="状态">
        <el-radio-group v-model="form.status">
          <el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
        </el-radio-group>
      </el-form-item>
      <el-form-item label="菜单权限">
        <el-checkbox v-model="menuExpand" @change="handleTreeExpand">展开/折叠</el-checkbox>
        <el-checkbox v-model="menuNodeAll" @change="handleTreeNodeAll">全选/全不选</el-checkbox>
        <el-checkbox v-model="menuCheckStrictly">父子联动</el-checkbox>
        <el-tree
          class="tree-border"
          :data="menuOptions"
          show-checkbox
          ref="treeRef"
          node-key="id"
          :check-strictly="!menuCheckStrictly"
          empty-text="加载中，请稍候"
          :props="{ label: 'name', children: 'children' }" />
      </el-form-item>
      <el-form-item label="备注">
        <el-input v-model="form.remark" type="textarea" placeholder="请输入内容" maxlength="250" />
      </el-form-item>
    </el-form>
    <div class="dialog-footer">
      <el-button class="medium" type="primary" :loading="submitting" :disabled="loading" @click="submitForm"
        >确 定</el-button
      >
      <el-button class="medium" @click="visible = false">取 消</el-button>
    </div>
  </el-dialog>
</template>
<script setup name="RoleForm">
  import { infoRoleApi, addRoleApi, editRoleApi } from '@/api/system/role'
  import { selectMenuApi } from '@/api/system/menu'

  const props = defineProps({ row: Object, moduleName: String })
  const visible = defineModel()
  const { proxy } = getCurrentInstance()

  const menuCheckStrictly = ref(false)
  const form = ref({
    name: '',
    role_key: '',
    list_sort: 10,
    status: '1',
    remark: '',
    check_strictly: '0',
    menu_ids: []
  })
  const rules = ref({
    name: [{ required: true, message: '角色名称不能为空', trigger: 'blur' }],
    role_key: [{ required: true, message: '权限字符不能为空', trigger: 'blur' }],
    list_sort: [{ required: true, message: '角色顺序不能为空', trigger: 'blur' }]
  })
  const { sys_normal_disable } = proxy.useDict('sys_normal_disable')

  // 初始化
  const title = ref('')
  const loading = ref(false)
  onMounted(async () => {
    loading.value = true
    form.value.id = props.row?.id || undefined
    if (form.value.id) {
      title.value = '编辑' + props.moduleName
      await getRowData()
    } else {
      title.value = '添加' + props.moduleName
    }
    await getMenuOptions()
    loading.value = false
  })

  // 获取数据
  async function getRowData() {
    try {
      const { info } = await infoRoleApi(form.value.id)
      form.value = proxy.dataToForm(form.value, info)
      menuCheckStrictly.value = form.value.check_strictly === '1'
    } catch (error) {
      visible.value = false
    }
  }

  // 提交按钮
  const emit = defineEmits(['submit'])
  const formRef = useTemplateRef('formRef')
  const submitting = ref(false)
  async function submitForm() {
    try {
      const valid = await formRef.value.validate()
      if (!valid) return
    } catch (error) {
      return
    }
    if (submitting.value) return
    submitting.value = true
    form.value.menu_ids = getAllCheckedKeys()
    form.value.check_strictly = menuCheckStrictly.value ? '1' : '0'
    try {
      await proxy.$modal.confirm('确定提交表单数据？')
      if (form.value.id) {
        await editRoleApi(form.value)
      } else {
        await addRoleApi(form.value)
      }
      emit('submit')
      proxy.$modal.msgSuccess('操作成功')
      visible.value = false
    } catch (e) {
      submitting.value = false
    }
  }

  // 获取菜单树列表
  const menuOptions = ref([])
  async function getMenuOptions() {
    try {
      const { list } = await selectMenuApi()
      menuOptions.value = proxy.listToTree(list)
      nextTick(() => {
        form.value.menu_ids.map(id => {
          treeRef.value.setChecked(id, true, false)
        })
      })
    } catch (error) {}
  }

  const treeRef = useTemplateRef('treeRef')
  // 所有菜单选中节点数据
  function getAllCheckedKeys() {
    let checkedKeys = treeRef.value.getCheckedKeys() // 目前被选中的菜单节点
    let halfCheckedKeys = treeRef.value.getHalfCheckedKeys() // 半选中的菜单节点
    checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
    return checkedKeys
  }

  // 树权限 （展开/折叠）
  const menuExpand = ref(false)
  function handleTreeExpand(checked) {
    let treeList = menuOptions.value
    for (let i = 0; i < treeList.length; i++) {
      treeRef.value.store.nodesMap[treeList[i].id].expanded = checked
    }
  }

  // 树权限（全选/全不选）
  const menuNodeAll = ref(false)
  function handleTreeNodeAll(checked) {
    treeRef.value.setCheckedNodes(checked ? menuOptions.value : [])
  }
</script>
